package cn.csc.module.product.controller.app.spu;

import cn.csc.framework.common.pojo.CommonResult;
import cn.csc.framework.common.pojo.PageResult;
import cn.csc.framework.security.core.annotations.PreAuthenticated;
import cn.csc.module.product.api.category.dto.CategoryRespDTO;
import cn.csc.module.product.controller.admin.spu.vo.*;
import cn.csc.module.product.controller.app.spu.vo.AppSpuSearchPageReqVO;
import cn.csc.module.product.convert.spu.SpuConvert;
import cn.csc.module.product.dal.dataobject.spu.SpuDO;
import cn.csc.module.product.dal.dataobject.spudetail.SpuDetailDO;
import cn.csc.module.product.service.category.CategoryService;
import cn.csc.module.product.service.spu.SpuService;
import cn.csc.module.product.service.spudetail.SpuDetailService;
import cn.csc.module.product.validated.Verify1;
import cn.csc.module.shop.api.detail.ShopDetailApi;
import cn.hutool.core.util.RandomUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Operation;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

import static cn.csc.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.csc.framework.common.pojo.CommonResult.success;
import static cn.csc.module.product.enums.ErrorCodeConstants.SPU_NOT_EXISTS;

/**
 * @author: 云隐
 * @Date: 2024/01/09
 **/
@Api(tags = "用户APP - 商品信息")
@RestController("appSpuController")
@RequestMapping("/product/spu")
@Validated
@Slf4j
@Setter
public class AppSpuController {

    @Autowired
    private SpuService spuService;
    @Autowired
    private SpuDetailService spuDetailService;
    @Autowired
    private CategoryService categoryService;
    @Resource
    ShopDetailApi shopDetailApi;


    @PostMapping("/create")
    @Operation(summary = "创建商品", description = "创建商品")
    @PreAuthenticated
    public CommonResult<BigInteger> appCreateSpu(@Validated @RequestBody SpuCreateDataReqVO createDataReqVO) {
        BigInteger id = spuService.createSpu(createDataReqVO);
        return success(id);
    }

    @GetMapping("/getById")
    @Operation(summary = "商品详情", description = "商品详情")
    @PreAuthenticated
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class)
    })
    public CommonResult<SpuDataRespVO> getById(@RequestParam BigInteger id) {
        SpuDataRespVO respVO = spuService.getSpuById(id);
        return success(respVO);
    }

    @GetMapping("/detailById")
    @Operation(summary = "商品详情", description = "商品详情")
    @PreAuthenticated
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class)
    })
    public CommonResult<SpuDataRespVO> detailById(@RequestParam BigInteger id) {
        SpuDataRespVO respVO = spuService.getSpuById(id);
        if (respVO == null || respVO.getVerifyStatus() != 10)
            throw exception(SPU_NOT_EXISTS);
        return success(respVO);
    }

    @GetMapping("/detailNum")
    @Operation(summary = "商品详情访问次数叠加", description = "商品详情访问次数叠加")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class)
    })
    @PreAuthenticated
    public CommonResult<Boolean> detailNum(@RequestParam("id") BigInteger id) {
        spuDetailService.detailNum(id);
        return success(true);
    }

    @GetMapping("/hot")
    @Operation(summary = "热卖精选", description = "热卖精选")
    @PreAuthenticated
    public CommonResult<List<SpuDataRespVO>> getHot(){
        List<SpuDataRespVO> hot = spuDetailService.getHot();
        return CommonResult.success(hot);
    }

    @GetMapping("/search")
    @Operation(summary = "商品搜索", description = "商品搜索")
    @PreAuthenticated
    public CommonResult<PageResult<SpuDataRespVO>> search(AppSpuSearchPageReqVO reqVO){
        PageResult<SpuDataRespVO> search = spuDetailService.searchLikeSpuName(reqVO);
        return CommonResult.success(search);
    }


    @PostMapping("/shelf")
    @Operation(summary = "商品上下架", description = "商品上下架")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class),
            @ApiImplicitParam(name = "verifyStatus", required = true, value = "审核状态", example = "1", dataTypeClass = Integer.class)
    })
    @PreAuthenticated
    public CommonResult<Boolean> shelf(@Validated @RequestBody SpuShelfReqVO spuShelfReqVO) {
        SpuUpdateReqVO reqVO = new SpuUpdateReqVO();
        reqVO.setId(spuShelfReqVO.getId());
        reqVO.setVerifyStatus(spuShelfReqVO.getVerifyStatus());
        spuService.onShelf(reqVO);
        return success(true);
    }

    @PostMapping("/updateSpu")
    @Operation(summary = "修改商品", description = "修改商品")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class),
            @ApiImplicitParam(name = "verifyStatus", required = true, value = "审核状态", example = "1", dataTypeClass = Integer.class)
    })
    @PreAuthenticated
    public CommonResult<Boolean> updateSpu(@Validated(Verify1.class) @RequestBody SpuCreateDataReqVO createDataReqVO) {
        spuService.updateSpu(createDataReqVO);
        return success(true);
    }

    @PostMapping("/shopSpu")
    @Operation(summary = "加入企业购", description = "加入企业购")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", required = true, value = "商品ID", example = "1", dataTypeClass = BigInteger.class),
            @ApiImplicitParam(name = "verifyStatus", required = true, value = "审核状态", example = "1", dataTypeClass = Integer.class)
    })
    @PreAuthenticated
    public CommonResult<Boolean> addShopSpu(@Validated(Verify1.class) @RequestBody List<SpuShopDataReqVO> list) {
        spuService.addShopSpuBatch(list);
        return success(true);
    }

    @GetMapping("/index")
    @ApiOperation("首页商品列表")
    @PreAuthenticated
    @ApiImplicitParams({
            @ApiImplicitParam(name = "categoryId", required = false, value = "分类ID", example = "1", dataTypeClass = BigInteger.class)
    })
    public CommonResult<PageResult<SpuRespVO>> getSpuPage(SpuPageReqVO pageVO) {
        pageVO.setVerifyStatus(10);
        if (pageVO.getCategoryId() != null) {
            List<CategoryRespDTO> list = categoryService.topItemList(pageVO.getCategoryId());
            List<BigInteger> ids = list.stream().map(CategoryRespDTO::getId).collect(Collectors.toList());
            if (ids != null && !ids.isEmpty())
                pageVO.setCategoryList(ids);
        }
        PageResult<SpuDO> pageResult = spuService.getSpuPageSingle(pageVO);
        Optional.ofNullable(pageResult.getList()).ifPresent(s -> {
            s.forEach(t -> {
                t.setSeq(Integer.parseInt(RandomUtil.randomNumbers(6)));
            });
        });
        Optional.ofNullable(pageResult.getList()).ifPresent(s -> {
            List<SpuDO> list = s.stream().sorted(Comparator.comparing(j -> j.getSeq(), Comparator.reverseOrder())).collect(Collectors.toList());
            pageResult.setList(list);
        });
        return success(SpuConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/list")
    @ApiOperation("店铺商品列表")
    @PreAuthenticated
    @ApiImplicitParams({
            @ApiImplicitParam(name = "shopId", required = true, value = "店铺ID", example = "1", dataTypeClass = BigInteger.class),
            @ApiImplicitParam(name = "statusList", required = false, value = "状态集合", example = "1", dataTypeClass = List.class)
    })
    public CommonResult<PageResult<SpuRespVO>> getSpuListPage(@Valid SpuPageReqVO pageVO) {
        PageResult<SpuDO> pageResult = spuService.getSpuPage(pageVO);
        return success(SpuConvert.INSTANCE.convertPage(pageResult));
    }

    @GetMapping("/productList")
    @ApiOperation("店铺进入商品")
    @PreAuthenticated
    @ApiImplicitParams({
            @ApiImplicitParam(name = "shopId", required = true, value = "店铺ID", example = "1", dataTypeClass = BigInteger.class)
    })
    public CommonResult<PageResult<SpuRespVO>> getSpuListIndexPage(@Valid SpuPageReqVO pageVO) {
        List<String> list = new ArrayList<>();
        list.add("10");
        pageVO.setStatusList(list);
        PageResult<SpuDO> pageResult = spuService.getSpuPage(pageVO);
        return success(SpuConvert.INSTANCE.convertPage(pageResult));
    }

    /**
     * 查询推荐商品热点
     *
     * @param
     * @return
     */
    @GetMapping("/recommend")
    @ApiOperation("推荐热品数据")
    @PreAuthenticated
    public CommonResult<List<SpuRespVO>> recommend() {
        List<SpuDetailDO> list = spuDetailService.selectListDetailNum();
        log.info("=====推荐商品1=========={}",list);
        List<SpuRespVO> rlist = new ArrayList<>();
        if (list != null && !list.isEmpty()) {
            if (list.size() >= 10) {
                List<BigInteger> tlist = list.stream().map(SpuDetailDO::getId).collect(Collectors.toList());
                List<SpuDO> slist = spuService.getSpuList(tlist);
                Optional.ofNullable(slist).ifPresent(s -> {
                    s.forEach(t -> {
                        t.setSeq(Integer.parseInt(RandomUtil.randomNumbers(6)));
                    });
                });

                if (slist != null && !slist.isEmpty()) {
                    List<SpuDO> list1 = slist.stream().sorted(Comparator.comparing(j -> j.getSeq(), Comparator.reverseOrder())).limit(3).collect(Collectors.toList());
                    rlist = SpuConvert.INSTANCE.convertList(list1);
                }
            }
        }
        log.info("=====推荐商品=========={}",rlist);
        return success(rlist);
    }

    @DeleteMapping("/delete")
    @ApiOperation("删除商品信息")
    @PreAuthenticated
    @ApiImplicitParam(name = "id", value = "商品ID", required = true, dataTypeClass = BigInteger.class)
    public CommonResult<Boolean> deleteSpu(@RequestParam("id") BigInteger id) {
        spuService.deleteSpu(id);
        return success(true);
    }
}
